package org.example.l0;

import org.example.l2.CharHelper;

import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
 * {@link com.jayway.jsonpath.spi.cache.LRUCache}
 */
public class LRUCache {

    public static void main(String[] args) {
        char[][] from = CharHelper.from("[[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]]");
        String[] str = new String[]{"put", "put", "get", "put", "get", "put", "get", "get", "get"};
        LRUCache lruCache = new LRUCache(2);
        for (int i = 0; i < str.length; i++) {
            String s = str[i];
            char[] chars = from[i];
            if (s.equals("put")) {
                lruCache.put(chars[0], chars[1]);
            } else {
                int i1 = lruCache.get(chars[0]);
                System.out.println(i1);
            }
        }
    }

    Map<Integer, Integer> map = new HashMap<>();
    Deque<Integer> deque = new LinkedList<>();

    int limit;

    public LRUCache(int capacity) {
        this.limit = capacity;
    }

    public void put(int key,
                    int value) {
        Integer old = map.put(key, value);
        if (old != null) {
            reAdd(key);
        } else {
            add(key);
        }

        if (map.size() > limit) {
            map.remove(removeEldest());
        }
    }

    public int get(int key) {
        Integer v = map.get(key);
        if (v == null) {
            return -1;
        }
        reAdd(key);
        return v;
    }

    void add(Integer key) {
        deque.addFirst(key);
    }

    void reAdd(Integer key) {
        deque.removeFirstOccurrence(key);
        deque.addFirst(key);
    }

    Integer removeEldest() {
        Integer key = deque.removeLast();
        return key;
    }
}